package com.dems.service.org.manager;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dems.dao.dataobject.Dept;
import com.dems.dao.dataobject.DeptStaff;
import com.dems.dao.dataobject.StaffRole;
import com.dems.dao.dataobject.User;
import com.dems.dao.mapper.la.DeptMapper;
import com.dems.dao.mapper.la.DeptStaffMapper;
import com.dems.dao.mapper.la.StaffRoleMapper;
import com.dems.dao.mapper.la.UserMapper;
import com.dems.domain.UserReqVO;
import com.dems.domain.enumerate.UserTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.apache.commons.collections4.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 人员机构关系
 */
@Slf4j
@Component
public class StaffManager {

    @Autowired
    UserMapper userMapper;

    @Autowired
    DeptMapper deptMapper;

    @Autowired
    DeptStaffMapper deptStaffMapper;

    @Autowired
    StaffRoleMapper staffRoleMapper;

    /**
     * 获取超管用户
     * @return
     */
    public List<User> fetchTUser() {
        List<StaffRole> tStaffRoleList = staffRoleMapper.selectByRoleCode(Arrays.asList(UserTypeEnum.T.getCode()));
        List<User> tuserList = userMapper.selectByIdList(tStaffRoleList.stream()
                .map(StaffRole::getUserId).distinct().collect(Collectors.toList()));
        return tuserList;
    }

    /**
     * 获取员工岗位角色
     * @param userIdList
     * @return
     */
    public Map<String, StaffRole> fetchStaffRole(List<String> userIdList) {
        List<StaffRole> staffRoleList = staffRoleMapper.selectByUserIdList(userIdList);

        Map<String, StaffRole> staffRoleMap = new HashMap<>();

        if (CollectionUtils.isNotEmpty(staffRoleList)) {
            staffRoleMap = staffRoleList.stream().collect(Collectors.toMap(StaffRole::getUserId, Function.identity(), (x1, x2) -> x1));
        }
        return staffRoleMap;
    }

    /**
     * 获取上级信息
     * @param userId
     * @return
     */
    public User fetchSupervisor(String userId) {

        if (StringUtils.isBlank(userId)) {
            return null;
        }

        List<DeptStaff> deptStaffList = deptStaffMapper.selectByUserIdList(Arrays.asList(userId));

        if (CollectionUtils.isEmpty(deptStaffList)) {
            return null;
        }

        Dept dept = deptMapper.selectByPrimaryKey(deptStaffList.get(0).getDeptId());
        if (userId.equals(dept.getSupervisorIds())) {
            dept = deptMapper.selectByPrimaryKey(dept.getSuperId());
        }
        if (StringUtils.isBlank(dept.getSupervisorIds())) {
            return null;
        }
        User user = userMapper.selectByPrimaryKey(dept.getSupervisorIds());

        if (user == null) {
            return null;
        }

        List<StaffRole> staffRoleList = staffRoleMapper.selectByUserId(user.getUserId());
        if (CollectionUtils.isNotEmpty(staffRoleList)) {
            user.setRoleCodeList(staffRoleList.stream().map(StaffRole::getRoleCode).distinct().collect(Collectors.toList()));
        }
        return user;
    }

    /**
     * 获取上级信息
     * @param userId
     * @return
     */
    public Map<String, DeptStaff> fetchSupervisorBatch(String ... userId) {

        if (null == userId) {
            return new HashMap<>();
        }

        List<DeptStaff> deptStaffList = deptStaffMapper.selectByUserIdList(Arrays.asList(userId));
        if (CollectionUtils.isEmpty(deptStaffList)) {
            return new HashMap<>();
        }

        List<Long> deptIdList = deptStaffList.stream().map(DeptStaff::getDeptId).distinct().collect(Collectors.toList());
        List<Dept> deptList = deptMapper.selectByIdList(deptIdList);
        List<String> supervisorUserIdList = deptList.stream().map(Dept::getSupervisorIds)
                .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());

        if (CollectionUtils.isEmpty(supervisorUserIdList)) {
            return new HashMap<>();
        }

        List<DeptStaff> supervisorUserList = deptStaffMapper.selectByUserIdList(supervisorUserIdList);
        Map<String, DeptStaff> supervisorUserMap = supervisorUserList.stream().collect(Collectors.toMap(
                User::getUserId, Function.identity(), (x1, x2) -> x1));

        deptList.forEach(item -> item.setSupervisor(supervisorUserMap.get(item.getSupervisorIds())));

        Map<Long, DeptStaff> deptSupervisorMap = deptList.stream().filter(item -> item.getSupervisor() != null)
                .collect(Collectors.toMap(Dept::getId,
                Dept::getSupervisor, (x1, x2) -> x1));

        Map<String, DeptStaff> supervisorMap = new HashMap<>();

        deptStaffList.forEach(item -> {
            if (deptSupervisorMap.containsKey(item.getDeptId())) {
                supervisorMap.put(item.getUserId(), deptSupervisorMap.get(item.getDeptId()));
            }
        });
        return supervisorMap;
    }

    /**
     * 获取员工完整角色信息
     * @param userId
     * @return
     */
    public User fetchUserInfo(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        User user = userMapper.selectByPrimaryKey(userId);
        List<StaffRole> staffRoleList = staffRoleMapper.selectByUserId(userId);
        if (CollectionUtils.isNotEmpty(staffRoleList)) {
            user.setRoleCodeList(staffRoleList.stream().map(StaffRole::getRoleCode)
                    .distinct().collect(Collectors.toList()));
        }
        return user;
    }

    /**
     * 离职用户列表
     * @param userIdList
     * @return
     */
    public List<String> fetchFiredUser(List<String> userIdList) {
        if (CollectionUtils.isEmpty(userIdList)) {
            return null;
        }

        List<User> firedUser = userMapper.selectByIdList(userIdList);

        if (CollectionUtils.isEmpty(firedUser)) {
            return null;
        }


        return firedUser.stream().filter(item -> item.getStatus() == -1).map(User::getUserId).distinct().collect(Collectors.toList());

    }

    /**
     * 获取员工完整角色信息
     * @param userId
     * @return
     */
    public User fetchUserInfoWithL1(String userId) {
        User user = fetchUserInfo(userId);
        if (user == null) {
            return null;
        }
        List<DeptStaff> deptStaffList = deptStaffMapper.selectByUserIdList(Arrays.asList(userId));
        if (CollectionUtils.isEmpty(deptStaffList)) {
            return user;
        }

        Dept dept = deptMapper.selectByPrimaryKey(deptStaffList.get(0).getDeptId());

        if (dept == null || StringUtils.isBlank(dept.getSupervisorIds())) {
            return user;
        }
        user.setDeptId(dept.getId());
        user.setDeptName(dept.getDeptName());
        User supUser = fetchUserInfo(dept.getSupervisorIds());
        if (supUser == null) {
            return user;
        }

        user.setL1UserId(supUser.getUserId());
        user.setL1UserName(supUser.getName());
        user.setL1UserOpenId(supUser.getOpenId());
        return user;
    }
    /**
     * 获取员工完整角色信息
     * @param userId
     * @return
     */
    public User fetchUserInfoWithL1BySipAccount(String sipAccount) {
        User user = userMapper.selectBySipAccount(sipAccount, null);

        if (null == user) {
            return null;
        }

        String userId = user.getUserId();
        user = fetchUserInfo(user.getUserId());
        if (user == null) {
            return null;
        }
        List<DeptStaff> deptStaffList = deptStaffMapper.selectByUserIdList(Arrays.asList(userId));
        if (CollectionUtils.isEmpty(deptStaffList)) {
            return user;
        }

        Dept dept = deptMapper.selectByPrimaryKey(deptStaffList.get(0).getDeptId());

        if (dept == null || StringUtils.isBlank(dept.getSupervisorIds())) {
            return user;
        }

        User supUser = fetchUserInfo(dept.getSupervisorIds());
        if (supUser == null) {
            return user;
        }

        user.setL1UserId(supUser.getUserId());
        user.setL1UserName(supUser.getName());
        user.setL1UserOpenId(supUser.getOpenId());
        return user;
    }

    /**
     * 识别是否为负责范围
     * @param userId
     * @param userIdList
     * @return
     */
    public boolean checkBelong(String userId, String ... userIdList) {
        // 当前用户负责的所有部门以及子部门全部查出
        List<Dept> deptList = fetchOwnDept(userId);

        if (CollectionUtils.isEmpty(deptList)) {
            return Boolean.FALSE;
        }
        List<DeptStaff> deptStaffList = deptStaffMapper.selectByUserIdList(Arrays.asList(userIdList));
        if (CollectionUtils.isEmpty(deptStaffList)) {
            return Boolean.FALSE;
        }

        List<Long> deptIdList = deptList.stream().map(Dept::getId).distinct().collect(Collectors.toList());

        // 部门信息不在现有owner下
        deptStaffList = deptStaffList.stream().filter(item
                -> !deptIdList.contains(item.getDeptId())).collect(Collectors.toList());

        return CollectionUtils.isEmpty(deptStaffList);

    }

    /**
     * 获取全部负责部门与子部门
     * @param userId
     * @return
     */
    public List<Dept> fetchOwnDept(String userId) {
        if (StringUtils.isBlank(userId)) {
            return new ArrayList<>();
        }
        List<Dept> deptList = deptMapper.selectBySupervisor(Arrays.asList(userId));
        if(CollectionUtils.isEmpty(deptList)){
            List<DeptStaff> deptStaffList = deptStaffMapper.selectByUserIdList(Arrays.asList(userId));
            List<Long> deptIds = deptStaffList.stream().map(DeptStaff::getDeptId).distinct().collect(Collectors.toList());
            if (CollectionUtils.isEmpty(deptIds)) {
                return null;
            }
            deptList = deptMapper.selectByIdList(deptIds);
        }
        return fetchAllSubDept(deptList);
    }

    /**
     * 递归查找所有下级部门
     * @param superDept
     * @return
     */
    public List<Dept> fetchAllSubDept(List<Dept> superDept) {
        if (CollectionUtils.isEmpty(superDept)) {
            return new ArrayList<>();
        }
        List<Dept> subDeptList = deptMapper.selectBySuperId(superDept.stream().map(Dept::getId).collect(Collectors.toList()));
        if (CollectionUtils.isEmpty(subDeptList)) {
            return superDept;
        }

        List<Long> superDeptIdList = superDept.stream().map(Dept::getId).collect(Collectors.toList());

        subDeptList = subDeptList.stream().filter(item -> !superDeptIdList.contains(item.getId())).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(subDeptList)) {
            return superDept;
        }

        superDept.addAll(fetchAllSubDept(subDeptList));
        return superDept;
    }

    /**
     * 校验用户是否是同一部门
     * @return
     */
    public boolean belongTheSameDept(String ... userIdList) {
        List<DeptStaff> deptStaffList = deptStaffMapper.selectByUserIdList(Arrays.asList(userIdList));

        if (CollectionUtils.isEmpty(deptStaffList)) {
            return Boolean.FALSE;
        }

        List<Long> deptIdList = deptStaffList.stream().map(DeptStaff::getDeptId).distinct().collect(Collectors.toList());
        return deptIdList.size() == 1;
    }


    /**
     * 获取主管下所有员工
     * @param l1UserIdList
     * @return
     */
    public List<DeptStaff> getDirectSubDeptUser(List<String> l1UserIdList) {

        List<Dept> deptList = deptMapper.selectBySupervisor(l1UserIdList);

        if (CollectionUtils.isEmpty(deptList)) {
            return new ArrayList<>();
        }

        List<DeptStaff> deptStaffList = deptStaffMapper.selectByDeptIdList(deptList.stream().map(Dept::getId)
                .distinct().collect(Collectors.toList()));

        if (CollectionUtils.isEmpty(deptStaffList)) {
            return new ArrayList<>();
        }

        Map<Long, Dept> deptMap = deptList.stream().collect(Collectors.toMap(Dept::getId, Function.identity(), (x1, x2) -> x1));

        deptStaffList.forEach(item -> item.setSupervisorIds(deptMap.get(item.getDeptId()).getSupervisorIds()));

        deptStaffList = deptStaffList.stream().filter(item -> !l1UserIdList.contains(item.getUserId())).collect(Collectors.toList());

        return deptStaffList;
    }

    /**
     * partnerList 获取用户信息
     * @param userReqVO
     * @param user
     * @return
     */
    public Page<DeptStaff> fetchUser(UserReqVO userReqVO, User user) {
        return deptStaffMapper.selectPage(new Page<>(userReqVO.getPageNum(), userReqVO.getPageSize()),
                user.getUserId(), userReqVO.getName(),
                userReqVO.getPhoneNo(), userReqVO.getRoleCodeList(),
                userReqVO.getSupervisorIdsList());
    }

    public List<User> fetchUserList(List<String> userIdList) {
        List<User> userList = userMapper.selectByIdList(userIdList);

        Map<String, StaffRole> finalStaffRoleMap = fetchStaffRole(userIdList);

        userList.forEach(item -> {
            if (finalStaffRoleMap.containsKey(item.getUserId())) {
                item.setRoleCodeList(Arrays.asList(finalStaffRoleMap.get(item.getUserId()).getStaffRole().split(",")));
            }
        });

        return userList;
    }

    public List<User> fetchL1User() {
        List<String> supUserIdList = deptMapper.selectAllSupUser();

        return fetchUserList(supUserIdList);

    }

    public List<User> fetchVlUser() {
        List<StaffRole> tStaffRoleList = staffRoleMapper.selectByRoleCode(Arrays.asList(UserTypeEnum.VL.getCode()));

        if (CollectionUtils.isEmpty(tStaffRoleList)) {
            return new ArrayList<>();
        }

        List<User> vlUserList = userMapper.selectByIdList(tStaffRoleList.stream()
                .map(StaffRole::getUserId).distinct().collect(Collectors.toList()));
        return vlUserList;

    }

    public List<User> fetchBIZVUser() {
        List<StaffRole> tStaffRoleList = staffRoleMapper.selectByRoleCode(Arrays.asList(UserTypeEnum.BIZ_VISIT.getCode()));

        if (CollectionUtils.isEmpty(tStaffRoleList)) {
            return new ArrayList<>();
        }

        List<User> vlUserList = userMapper.selectByIdList(tStaffRoleList.stream()
                .map(StaffRole::getUserId).distinct().collect(Collectors.toList()));
        return vlUserList;

    }

    /**
     * 跟进城市获取接待
     * @param city
     * @return
     */
    public StaffRoleMapper fetchVUserByCity(String city) {

//        staffRoleMapper.selectVUserByCity(city);

        return null;
    }

    public Dept fetchBelongDeptByUserId(User loanassistUser) {
        List<DeptStaff> deptStaffList = deptStaffMapper.selectByUserIdList(Arrays.asList(loanassistUser.getUserId()));
        if (CollectionUtils.isEmpty(deptStaffList)) {
            return null;
        }

        return deptMapper.selectByPrimaryKey(deptStaffList.get(0).getDeptId());
    }

    public List<User> fetchPreBankUser() {
        List<User> preBankUser = userMapper.selectPreBankUser();
        return preBankUser;

    }
}
